package byron.server;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;

import byron.client.ByronClient;
import byron.client.CellData;

import com.csvreader.CsvReader;
import com.google.gwt.dev.util.collect.Lists;

/**
 * A concrete datasource utilizing CSV for data representation 
 *
 */
public class CsvSource implements DataSource{
	private Hashtable<String, List<CellData>> columns;
	private List<List<CellData>> rows;
	private String primaryKey;
	
	public String getPrimaryKey() {
		return primaryKey;
	}

	public void setPrimaryKey(String primaryKey) {
		this.primaryKey = primaryKey;
	}
	
	/**
	 * Creates the data source
	 * @param contents String containing a CSV-source
	 * @param primaryKey Primary key of this source
	 */
	public CsvSource(String contents, String primaryKey) {
		this.primaryKey = primaryKey;
		try {
			load(contents);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	private void parse(CsvReader r) throws IOException {
		columns = new Hashtable<String, List<CellData>>();
		rows = new ArrayList<List<CellData>>();
		
		r.readHeaders();
		String[] headers = r.getHeaders();
		for (String headername : headers) {
			columns.put(headername, new LinkedList<CellData>());
		}
		
		while (r.readRecord()) {
			ArrayList<CellData> row = new ArrayList<CellData>();
			rows.add(row);
			
			for (String headername : headers) {
				CellData cd = new CellData(r.get(headername));
				cd.setKey(r.get(primaryKey));
				columns.get(headername).add(cd);
				row.add(cd);
			}
			
		}
	}
	
	public List<String> getAttributes() {
		return Lists.create(columns.keySet().toArray(new String[1]));
	}
	
	public List<CellData> getColumn(String attributeName, String key) {
		List<CellData> selectedCols = new LinkedList<CellData>();
		
		for (CellData cd : columns.get(attributeName)) {
			if (cd.getKey().contains(key)) {
				selectedCols.add(cd);
			}
		}
		return selectedCols;
	}

	public void load(String contents) throws FileNotFoundException {
		try {
			CsvReader r = new CsvReader(new StringReader(contents), ';');
			parse(r);
			r.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public ArrayList<List<CellData>> getRows(String key) {
		ArrayList<List<CellData>> tempRows = new ArrayList<List<CellData>>();
		
		for (List<CellData> row : rows) {
			for (CellData cd : row) {
				if (cd.toString().contains(key)) {
					tempRows.add(row);
					break;
				}
			}
		}
		
		return tempRows;
	}
}
